package cn.wolfcode.car.business.service.impl;

import cn.wolfcode.car.business.domain.Appointment;
import cn.wolfcode.car.business.domain.Statement;
import cn.wolfcode.car.business.domain.StatementItem;
import cn.wolfcode.car.business.mapper.StatementItemMapper;
import cn.wolfcode.car.business.query.StatementItemQuery;
import cn.wolfcode.car.business.service.IAppointmentService;
import cn.wolfcode.car.business.service.IStatementItemService;
import cn.wolfcode.car.business.service.IStatementService;
import cn.wolfcode.car.common.base.page.TablePage;
import cn.wolfcode.car.common.base.page.TablePageInfo;
import cn.wolfcode.car.common.exception.BusinessException;
import cn.wolfcode.car.common.util.Convert;
import cn.wolfcode.car.common.util.StringUtils;
import cn.wolfcode.car.shiro.ShiroUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

@Service
@Transactional
public class StatementItemServiceImpl extends ServiceImpl<StatementItemMapper, StatementItem> implements IStatementItemService {

    @Autowired
    private StatementItemMapper statementItemMapper;

    @Autowired
    private IStatementService statementService;

    @Autowired
    private IAppointmentService appointmentService;

    @Override
    public TablePage<StatementItem> query(StatementItemQuery qo) {
        Page<StatementItem> page = new Page<>(qo.getPageNum(),qo.getPageSize());
        QueryWrapper<StatementItem> wrapper = Wrappers.<StatementItem>query();
        wrapper.eq(StringUtils.isNotNull(qo.getStatementId()),"statement_id",qo.getStatementId());
        statementItemMapper.selectPage(page, wrapper);
        return new TablePage<StatementItem>(page);
    }


    @Override
    public void add(StatementItem statementItem) {
        statementItemMapper.insert(statementItem);
    }

    @Override
    public StatementItem get(Long id) {
        return statementItemMapper.selectById(id);
    }


    @Override
    public void update(StatementItem statementItem) {
        statementItemMapper.updateById(statementItem);
    }

    @Override
    public void deleteBatch(String ids) {
        Long[] dictIds = Convert.toLongArray(ids);
        for (Long dictId : dictIds) {
            statementItemMapper.deleteById(dictId);
        }
    }

    @Override
    public List<StatementItem> list() {
        return statementItemMapper.selectList(Wrappers.emptyWrapper());
    }

    @Override
    @Transactional
    public void saveItems(List<StatementItem> list) {
        // 获取页面传入的StatementItem和折扣价格, 先取得折扣价格
        StatementItem item = list.remove(list.size() - 1);
        BigDecimal discountAmount = item.getItemPrice();
        // 取得结算单ID
        Long statementId = item.getStatementId();
        // 判断结算单状态是否是消费中,不是消费中不能保存
        Statement statement = statementService.get(statementId);
        if (!Statement.STATUS_CONSUME.equals(statement.getStatus())) {
            // 不是消费中状态不能保存
            throw new BusinessException("非消费中状态不能保存");
        }
        // 此时都是消费中状态,先存结算单明细,再存结算单中的总金额和总项数,折扣价格
        // 存结算单明细之前,先将该结算单之前的明细全部删除
        QueryWrapper<StatementItem> wrapper = Wrappers.<StatementItem>query();
        wrapper.eq("statement_id",statement.getId());
        this.deleteByStatementId(statement.getId());
        // 遍历计算总金额,总项数并保存结算单明细
        BigDecimal totalAmount = new BigDecimal("0.00");
        BigDecimal totalQuantity = new BigDecimal("0");
        for (StatementItem statementItem : list) {
            BigDecimal itemQuantity = statementItem.getItemQuantity();
            BigDecimal itemPrice = statementItem.getItemPrice();
            totalAmount = totalAmount.add(itemPrice.multiply(itemQuantity));
            totalQuantity = totalQuantity.add(itemQuantity);
            statementItemMapper.insert(statementItem);
        }
        // 判断折扣金额是否大于总金额
        if (discountAmount.compareTo(totalAmount) > 0) {
            throw new BusinessException("折扣金额不能大于总消费金额");
        }
        // 将总金额,总项数,折扣金额保存到结算单中
        statementService.updateConsumer(statementId,totalAmount, totalQuantity, discountAmount);
    }

    @Override
    @Transactional
    public void payStatement(Long statementId) {
        Statement statement = statementService.get(statementId);
        // 只有消费中才能支付,已支付的不能再次支付
        if (!Statement.STATUS_CONSUME.equals(statement.getStatus())) {
            throw new BusinessException("已支付的不能再次支付");
        }
        // 将statement的状态修改为已支付,并添加收款人ID和支付时间
        statementService.updatePaid(statementId, ShiroUtils.getUserId(), Statement.STATUS_PAID);
        // 如果是预约客户,则需要将预约客户的已到店修改为已结算
        Long appointmentId = statement.getAppointmentId();
        if (appointmentId != null) {
            // 表示是预约客户, 将预约客户的已到店修改为已结算
            appointmentService.changeStatus(appointmentId,Appointment.STATUS_SETTLE);
        }
    }

    @Override
    public void deleteByStatementId(Long id) {
        QueryWrapper<StatementItem> wrapper = Wrappers.<StatementItem>query();
        wrapper.eq("statement_id",id);
        statementItemMapper.delete(wrapper);
    }
}
